﻿using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Markup;

namespace MotionControl.Modules.PLC.Business
{
    public partial class PLCControl
    {
        public enum AxisType {
            InletBelt = 210,
            OutletBelt = 215,
            TopBelt = 220,
            TopCam = 225,
            BottomCam = 230,
            TopBeltElevating = 235,
            LightElevating = 240,
            Barrier = 300,
        }
        //Axis Control JOG+/JOG-/Back to the origin

        public void AxisControl(AxisType type, string cmd, float speed = 0, bool isInteger = false)
        {
            ushort addr = (ushort)type;
            switch (cmd)
            {
                case "!":
                    WriteSingle(addr, 0);
                    break;
                case "+":
                    WriteSingle(addr, 1);
                    break;
                case "-":
                    WriteSingle(addr, 2);
                    break;
                case "*!":
                    WriteSingle((ushort)(addr + 1), 0);
                    break;
                case "*":
                    WriteSingle((ushort)(addr + 1), 1);
                    break;
                case "s":
                    if (isInteger)
                        WriteSingle((ushort)(addr + 2), (short)speed);
                    else
                        WriteFloat(addr + 2, speed);                 
                     break;
            }
        }

        public enum BoolType
        {
            BackLight = 302,
            Blower1 = 304,
            Blower2 = 306,
            ChangeValve11 = 308,
            ChangeValve12 = 310,

            Start = 332,
            Stop = 333,
            Reset = 334,
            SingleOrCycle = 336,

            CamElevatingAxisEnable = 338,
            TopBeltAxisEnable = 339,
            Blower1Enable = 340,
            Blower2Enable = 341,
        }
        public void BoolControl(BoolType type, bool val, bool isTrigger = false)
        {
            ushort addr = (ushort)type;
            if (val)
            {
               
                WriteSingle(addr, 1);
                if (isTrigger)
                {
                    Thread.Sleep(200);
                    WriteSingle(addr, 0);
                }              
            }
            else
                WriteSingle(addr, 0);
        }

        public enum ValueType
        {
            BeltAutoSpeed = 312,
            BeltReturnSpeed = 314,
            PCBLength = 316,
            PCBThickness = 318,
            TopCamRefPos = 320,
            BottomCamRefPos = 322,
            TopElevatingJourney = 324,
            DistanceFromBarriarToLight = 326,
            PulseNumber = 328,
            CamTriggerDelay = 330,
            BarrierLiftupDelay = 331
        }
        public void ValueControl(ValueType type, float val = 0, bool isInteger = false)
        {
            ushort addr = (ushort)type;
            if (isInteger)
                WriteSingle(addr, (short)val);
            else
                WriteFloat(addr, val);
        }
        private void WriteFloat(int addr, float val)
        {
            var speedBytes = BitConverter.GetBytes(val);
            short highValue = BitConverter.ToInt16(speedBytes, 0);
            short lowValue = BitConverter.ToInt16(speedBytes, 2);

            var speedShorts = new short[] { highValue,lowValue };
            WriteMulti((ushort)(addr), speedShorts);
        }

        public Action<bool[]> boolMonitorAction;
        public Action<float[]> floatMonitorAction;

        private bool[] _boolArrary = new bool[29];
        private float[] _floatArrary = new float[4];
        private readonly bool number;

        private void BytesParse(short[] buffer)
        {
            if (buffer.Length < 22)
                return;
            int index = 0;
            for (int i = 0; i < 4; i++)     //D1.0--D1.3
            {
                _boolArrary[index++] = (buffer[1] >> i & 1) == 1;
            }
            for (int i = 5; i < 9; i++)     //D1.5--D1.8
            {
                _boolArrary[index++] = (buffer[1] >> i & 1) == 1;
            }
            for (int i = 10; i < 14; i++)   //D1.10--D1.13
            {
                _boolArrary[index++] = (buffer[1] >> i & 1) == 1;
            }
            for (int i = 0; i < 4; i++)     //D2.0--D2.3
            {
                _boolArrary[index++] = (buffer[2] >> i & 1) == 1;
            }
            for (int i = 10; i < 13; i++)     //D2.10--D2.12
            {
                _boolArrary[index++] = (buffer[2] >> i & 1) == 1;
            }
            for (int i = 0; i < 10; i++)     //D21.0--D21.9
            {
                _boolArrary[index++] = (buffer[21] >>i  & 1) == 1;
            }

            int baseIndex = 5;
            for (int i = 0; i < 4; i ++)     //D5.0--D12.0
            {
                var b1 = BitConverter.GetBytes(buffer[baseIndex + 2 * i]);
                var b2 = BitConverter.GetBytes(buffer[baseIndex + 2 * i + 1 ]);
                var bb = b1.Concat(b2).ToArray();
                _floatArrary[i] = BitConverter.ToSingle(bb, 0);
            }

            boolMonitorAction?.Invoke(_boolArrary);
            floatMonitorAction?.Invoke(_floatArrary);
        }
    }
}
